import React from 'react'
import { render } from 'react-dom'
import App from '../../App'

// 渲染页面 / 组件
const root = document.getElementById('root')

let hookStates = []
let hookIndex = 0

function stateRender() {
	hookIndex = 0
	render(<App />, root)
}

const useState = (initialValue) => {
	hookStates[hookIndex] = hookStates[hookIndex] ?? initialValue // 判断状态池里是否有老状态 没有就用初始值
	let currentIndex = hookIndex
	const setState = function (newState) {
		if (typeof newState === 'function') {
			hookStates[currentIndex] = newState(hookStates[currentIndex])
			stateRender()
		} else {
			hookStates[currentIndex] = newState
			stateRender()
		}
	}
	return [hookStates[hookIndex++], setState]
}

const useCallback = (callback, dependencies) => {
	if (hookStates[hookIndex] && dependencies) {
		// 状态池里缓存过这个函数 取出老的函数和依赖
		let [lastCallback, lastCallbackDeps] = hookStates[hookIndex]
		let same = dependencies.every((item, index) => item === lastCallbackDeps[index]) // 判断依赖的值是否变化
		if (same) {
			//如果老依赖和新的依赖都相同,则直接返回老的,如果不一相同,则返回新的
			hookIndex++
			return lastCallback
		} else {
			hookStates[hookIndex] = [callback, dependencies]
			return callback
		}
	} else {
		// 初始化 给进来是什么 就返回什么
		hookStates[hookIndex] = [callback, dependencies]
		return callback
	}
}

const useMemo = (factory, dependencies) => {
	if (hookStates[hookIndex] && dependencies) {
		let [memo, lastDeps] = hookStates[hookIndex]
		let same = dependencies.every((item, index) => item === lastDeps[index])
		if (same) {
			//如果老依赖和新的依赖都相同,则直接返回老的,如果不一相同,则返回新的
			hookIndex++
			return memo
		} else {
			let newMemo = factory()
			hookStates[hookIndex] = [newMemo, dependencies]
			return newMemo
		}
	} else {
		let newMemo = factory()
		hookStates[hookIndex] = [newMemo, dependencies]
		return newMemo
	}
}

const useEffect = (callback, dependencies) => {
	if (hookStates[hookIndex] && dependencies) {
		let lastDeps = hookStates[hookIndex]
		let same = dependencies.every((item, index) => item === lastDeps[index])
		if (same) {
			hookIndex++
		} else {
			hookStates[hookIndex++] = dependencies
			setTimeout(callback)
		}
	} else {
		hookStates[hookIndex++] = dependencies
		setTimeout(callback)
	}
}

const useLayoutEffect = (callback, dependencies) => {
	if (hookStates[hookIndex] && dependencies) {
		let lastDeps = hookStates[hookIndex]
		let same = dependencies.every((item, index) => item === lastDeps[index])
		if (same) {
			hookIndex++
		} else {
			hookStates[hookIndex++] = dependencies
			queueMicrotask(callback)
		}
	} else {
		hookStates[hookIndex++] = dependencies
		queueMicrotask(callback)
	}
}

const useContext = (context) => {
	return context._currentValue
}

export { useState, useCallback, useMemo, useEffect, useLayoutEffect, useContext }
